package pkg

import (
	"database/sql/driver"
	"encoding/json"
	"errors"
	"fmt"
	"gorm.io/gorm"
	"time"
)

type DO struct {
	CreatedAt time.Time      `gorm:"comment:创建时间"`
	UpdatedAt time.Time      `gorm:"comment:更新时间"`
	DeletedAt gorm.DeletedAt `gorm:"index;comment:删除时间"`
}

// 自定义数组类型----------------------------------------------------
type CustomArray []interface{}

func (m *CustomArray) Scan(value interface{}) error {
	if value == nil {
		*m = nil
		return nil
	}

	jsonValue, ok := value.([]byte)
	if !ok {
		return errors.New("failed to scan CustomArray")
	}

	var data []interface{}
	if err := json.Unmarshal(jsonValue, &data); err != nil {
		return err
	}

	*m = CustomArray(data)
	return nil
}

func (m CustomArray) Value() (driver.Value, error) {
	if m == nil {
		return nil, nil
	}

	jsonValue, err := json.Marshal(m)
	if err != nil {
		return nil, err
	}

	return jsonValue, nil
}

// 自定义结构体-----------------------------------------------------
type CustomObject struct {
	Field1 string
	Field2 int
}

// 实现 Scan 接口
func (m *CustomObject) Scan(value interface{}) error {
	// 将数据库字段的值转换为自定义对象类型
	if value == nil {
		*m = CustomObject{}
	} else if v, ok := value.([]byte); ok {
		if err := json.Unmarshal(v, m); err != nil {
			return err
		}
	} else {
		return errors.New("failed to scan CustomObject")
	}
	return nil
}

// 实现 Value 接口
func (m CustomObject) Value() (driver.Value, error) {
	// 将自定义对象类型转换为数据库字段的值
	return json.Marshal(m)
}

// ///////////////////////////////////////////////////////////
// CustomMap 参数
type CustomMap map[string]interface{}

// Scan Scanner 反序列化
func (args *CustomMap) Scan(value interface{}) error {
	if value == nil {
		return nil
	}

	b, ok := value.([]byte)
	if !ok {
		return fmt.Errorf("value is not []byte, value: %v", value)
	}

	return json.Unmarshal(b, &args)
}

// Value Valuer 序列化
func (args CustomMap) Value() (driver.Value, error) {
	if args == nil {
		return nil, nil
	}

	return json.Marshal(args)
}

/*
//m := make(model.CustomMap)
//m["color"] = 1
//m["size"] = 4

model.CustomMap{"color": 1, "size": 4}
*/
